package com.example.his.api.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaMode;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.json.JSONUtil;
import com.alipay.api.internal.util.file.IOUtils;
import com.example.his.api.common.MinioUtil;
import com.example.his.api.common.PageUtils;
import com.example.his.api.common.R;
import com.example.his.api.controller.form.*;
import com.example.his.api.db.pojo.GoodsEntity;
import com.example.his.api.mis.service.GoodsService;
import io.lettuce.core.dynamic.annotation.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

@RestController ( "MisGoodsController" )
@RequestMapping ( "/mis/goods" )
public class GoodsController {

  // 引入 Service
  @Resource
  private GoodsService goodsService;
  @Autowired
  private MinioUtil minioUtil;

  /**
   * 商品分页查询接口
   *
   * @param form 包含分页参数和查询条件的表单对象
   * @return 返回分页查询结果
   */
  @PostMapping ( "/searchByPage" )
  @SaCheckPermission ( value = { "ROOT", "GOODS:SELECT" }, mode = SaMode.OR )
  public R searchByPage( @Valid @RequestBody SearchGoodsByPageForm form ) {

    int page = form.getPage();
    int length = form.getLength();

    if ( page < 1 || length < 1 ) {
      return R.error( "分页参数非法: page≥1, length≥1" );
    }

    Map < String, Object > param = BeanUtil.beanToMap( form, false, true );
    param.put( "start", ( page - 1 ) * length );
    param.put( "length", length );

    PageUtils pageUtils = goodsService.searchByPage( param );
    return R.ok().put( "page", pageUtils );
  }

  /**
   * 商品图片上传接口
   *
   * @param file 上传的图片文件
   * @return 返回上传后的文件访问路径
   */
  @PostMapping ( value = "/uploadImage", consumes = MediaType.MULTIPART_FORM_DATA_VALUE )
  @SaCheckPermission ( value = { "ROOT", "GOODS:INSERT", "GOODS:UPDATE" }, mode = SaMode.OR )
  public R uploadImage( @RequestParam ( "file" ) MultipartFile file ) {
    String url = goodsService.uploadImage( file );
    return R.ok().put( "url", url );
  }

  /**
   * 新增商品接口
   *
   * @param form 包含商品信息的表单对象，需通过验证
   * @return 返回操作结果，包括插入的记录数
   */
  @PostMapping ( "/insert" )
  @SaCheckPermission ( value = { "ROOT", "GOODS:INSERT" }, mode = SaMode.OR )
  public R insert( @Valid @RequestBody InsertGoodsForm form ) {
    // 将表单对象转换为实体对象，忽略特定字段
    GoodsEntity entity = BeanUtil.toBean( form, GoodsEntity.class, CopyOptions.create().setIgnoreProperties(
        "checkup_1", "checkup_2", "checkup_3", "checkup_4", "tag" ) );

    String temp = null;

    // 处理 checkup_1 字段
    if ( form.getCheckup_1() != null ) {
      temp = JSONUtil.parseArray( form.getCheckup_1() ).toString();
      entity.setCheckup_1( temp );
    }

    // 处理 checkup_2 字段
    if ( form.getCheckup_2() != null ) {
      temp = JSONUtil.parseArray( form.getCheckup_2() ).toString();
      entity.setCheckup_2( temp );
    }

    // 处理 checkup_3 字段
    if ( form.getCheckup_3() != null ) {
      temp = JSONUtil.parseArray( form.getCheckup_3() ).toString();
      entity.setCheckup_3( temp );
    }

    // 处理 checkup_4 字段
    if ( form.getCheckup_4() != null ) {
      temp = JSONUtil.parseArray( form.getCheckup_4() ).toString();
      entity.setCheckup_4( temp );
    }

    // 处理 tag 字段
    if ( form.getTag() != null ) {
      temp = JSONUtil.parseArray( form.getTag() ).toString();
      entity.setTag( temp );
    }

    // 调用服务层插入数据
    int rows = goodsService.insert( entity );

    // 返回操作结果
    return R.ok().put( "rows", rows );
  }

  /**
   * 根据ID查询商品信息接口
   *
   * @param form 包含商品ID的表单对象，需通过验证
   * @return 返回查询到的商品信息
   */
  @PostMapping ( "/searchById" )
  @SaCheckPermission ( value = { "ROOT", "GOODS:SELECT" }, mode = SaMode.OR )
  public R searchById( @RequestBody @Valid SearchGoodsByIdForm form ) {

    HashMap map = goodsService.searchById( form.getId() );

    return R.ok().put( "result", map );
  }

  /**
   * 修改商品信息接口
   *
   * @param form 包含商品更新信息的表单对象，需通过验证
   * @return 返回操作结果，包括更新的记录数
   */
  @PostMapping ( "/update" )
  @SaCheckPermission ( value = { "ROOT", "GOODS:UPDATE" }, mode = SaMode.OR )
  public R update( @Valid @RequestBody UpdateGoodsForm form ) {

    // 将表单对象转换为实体对象，忽略特定字段
    GoodsEntity entity = BeanUtil.toBean( form, GoodsEntity.class, CopyOptions.create().setIgnoreProperties(
        "checkup_1", "checkup_2", "checkup_3", "checkup_4", "tag" ) );

    String temp = null;

    // 处理 checkup_1 字段
    if ( form.getCheckup_1() != null ) {
      temp = JSONUtil.parseArray( form.getCheckup_1() ).toString();
      entity.setCheckup_1( temp );
    }

    // 处理 checkup_2 字段
    if ( form.getCheckup_2() != null ) {
      temp = JSONUtil.parseArray( form.getCheckup_2() ).toString();
      entity.setCheckup_2( temp );
    }

    // 处理 checkup_3 字段
    if ( form.getCheckup_3() != null ) {
      temp = JSONUtil.parseArray( form.getCheckup_3() ).toString();
      entity.setCheckup_3( temp );
    }

    // 处理 checkup_4 字段
    if ( form.getCheckup_4() != null ) {
      temp = JSONUtil.parseArray( form.getCheckup_4() ).toString();
      entity.setCheckup_4( temp );
    }

    // 处理 tag 字段
    if ( form.getTag() != null ) {
      temp = JSONUtil.parseArray( form.getTag() ).toString();
      entity.setTag( temp );
    }

    // 调用服务层更新数据
    int rows = goodsService.update( entity );

    // 返回操作结果
    return R.ok().put( "rows", rows );
  }

  /**
   * 上传商品检查项文件接口
   *
   * @param form 包含商品ID的表单对象，用于关联上传的文件
   * @param file 上传的检查项文件（Excel格式）
   * @return 返回上传后的文件访问路径
   */
  @PostMapping ( "/uploadCheckupExcel" )
  @SaCheckPermission ( value = { "ROOT", "GOODS:INSERT", "GOODS:UPDATE" }, mode = SaMode.OR )
  public R uploadCheckupExcel( @Valid UploadCheckupExcelForm form,
                               @Param ( "file" ) MultipartFile file ) {
    goodsService.updateCheckup( form.getId(), file );
    return R.ok();
  }

  // 文件下载
  @GetMapping ( "/downloadCheckupExcel" )
  @SaCheckPermission ( value = { "ROOT", "GOODS:SELECT", "GOODS:INSERT", "GOODS:UPDATE" }, mode = SaMode.OR )
  public void downloadCheckupExcel( @Valid DownloadCheckupExcelForm form, HttpServletResponse response ) {

    // 设置文件下载名称
    response.setHeader( "Content-Disposition",
        "attachment;filename=" + form.getId() + ".xlsx" );

    //该MIME类型会让浏览器弹出下载对话框
    response.setContentType( "application/x-download" );
    response.setCharacterEncoding( "utf-8" );
    String path = "/mis/goods/checkup/" + form.getId() + ".xlsx";

    try {

      // 读取Minio储存文件的输入流
      InputStream inputStream = minioUtil.downloadFile( path );
      BufferedInputStream bufferedInputStream = new BufferedInputStream( inputStream );
      // 向响应式数据输入流
      ServletOutputStream outputStream = response.getOutputStream();
      BufferedOutputStream bufferedOutputStream = new BufferedOutputStream( outputStream );

      // 把输入流中的数据拷贝到输出流中
      IOUtils.copy( bufferedInputStream, bufferedOutputStream );

    }
    catch ( Exception e ) {
      // 抛出异常
      throw new RuntimeException( "文件下载失败" );
    }

  }

  /**
   * 修改商品状态接口
   *
   * @param form 包含商品ID和状态的表单对象，需通过验证
   * @return 返回操作结果，包括更新状态是否成功
   */
  @PostMapping ( "/updateStatus" )
  @SaCheckPermission ( value = { "ROOT", "GOODS:UPDATE" }, mode = SaMode.OR )
  public R updateStatus( @Valid @RequestBody UpdateGoodsStatusForm form ) {
    // 将表单对象转换为Map参数
    Map param = BeanUtil.beanToMap( form );
    // 调用服务层更新状态
    boolean bool = goodsService.updateStatus( param );
    // 返回操作结果
    return R.ok().put( "result", bool );
  }

  /**
   * 批量删除商品接口
   *
   * @param form 包含要删除的商品ID数组的表单对象，需通过验证
   * @return 返回操作结果，包括删除的记录数
   */
  @PostMapping ( "/deleteByIds" )
  @SaCheckPermission ( value = { "ROOT", "GOODS:DELETE" }, mode = SaMode.OR )
  public R deleteByIds( @Valid @RequestBody DeleteGoodsByIdsForm form ) {
    // 调用服务层执行批量删除操作
    int rows = goodsService.deleteByIds( form.getIds() );
    // 返回删除成功的记录数
    return R.ok().put( "rows", rows );
  }

}
